﻿#include "filtablesortproxymodel.h"

FilTableSortProxyModel::FilTableSortProxyModel(QObject *parent)
    : QSortFilterProxyModel{parent}
{
    connect(this, &FilTableSortProxyModel::modelChanged, this,
            [=] { setSourceModel(this->model().value<QAbstractTableModel *>()); });
}

bool FilTableSortProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
    QJSValue filter = _filter;
    if (filter.isUndefined()) {
        return true;
    }
    QJSValueList data;
    data << sourceRow;
    return filter.call(data).toBool();
}

bool FilTableSortProxyModel::filterAcceptsColumn(int sourceColumn, const QModelIndex &sourceParent) const
{
    return true;
}

bool FilTableSortProxyModel::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const
{
    QJSValue comparator = _comparator;
    if (comparator.isUndefined()) {
        return true;
    }
    QJSValueList data;
    data << sourceLeft.row();
    data << sourceRight.row();
    bool flag = comparator.call(data).toBool();
    if (sortOrder() == Qt::AscendingOrder) {
        return !flag;
    } else {
        return flag;
    }
}

QVariant FilTableSortProxyModel::getRow(int rowIndex)
{
    QVariant result;
    QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "getRow",
                              Q_RETURN_ARG(QVariant, result),
                              Q_ARG(int, mapToSource(index(rowIndex, 0)).row()));
    return result;
}

void FilTableSortProxyModel::setRow(int rowIndex, const QVariant &val)
{
    QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "setRow",
                              Q_ARG(int, mapToSource(index(rowIndex, 0)).row()),
                              Q_ARG(QVariant, val));
}

void FilTableSortProxyModel::insertRow(int rowIndex, const QVariant &val)
{
    QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "insertRow",
                              Q_ARG(int, mapToSource(index(rowIndex, 0)).row()),
                              Q_ARG(QVariant, val));
}

void FilTableSortProxyModel::removeRow(int rowIndex, int rows)
{
    QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "removeRow",
                              Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(int, rows));
}

void FilTableSortProxyModel::setComparator(const QJSValue &comparator)
{
    int column = 0;
    if (comparator.isUndefined()) {
        column = -1;
    }
    this->_comparator = comparator;
    if (sortOrder() == Qt::AscendingOrder) {
        sort(column, Qt::DescendingOrder);
    } else {
        sort(column, Qt::AscendingOrder);
    }
}

void FilTableSortProxyModel::setFilter(const QJSValue &filter)
{
    this->_filter = filter;
    invalidateFilter();
}
